package com.adcc.foc.controller;

import com.adcc.foc.config.AppConfig;
import com.adcc.foc.domain.*;
import com.adcc.foc.service.OrganizationService;
import com.adcc.foc.service.UserService;
import com.adcc.foc.task.LoginRefreshTimer;
import com.adcc.foc.utils.*;
import net.sf.json.JSONArray;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
public class LoginController {

    @Resource
    private UserService userService;
    @Resource
    private OrganizationService organizationService;
    @Resource
    private AppConfig appConfig;

    @RequestMapping("/")
    public String index() {
        return "log_in";
    }

    /**
     * 用户名密码校验
     *
     * @param userName 账户名
     *                 password  密码
     * @author houxy
     */
    @RequestMapping("/checklogin")
    @ResponseBody
    public Map<String, Object> checkLogin(String userName, String password,String key, String verCode, HttpSession session,HttpServletRequest httpServletRequest) {
        Map<String, Object> map = new HashMap<String, Object>();
        Properties prop = new Properties();
        String msg = "";
        try {
            map.put("status",ResultState.ERROR);
            String imgCode = session.getAttribute("imgCode").toString();
            userName = CryptoUtil.decryptString(userName,key);
            password = CryptoUtil.decryptString(password,key);
            prop.load(UserUtil.class.getClassLoader().getResourceAsStream("app.properties"));
            msg = prop.getProperty("openVerCodeFlag");
            //用户锁定逻辑
            String ip = IpUtil.getRequestIp();
            Map<String,Object> lockMap = LoginRefreshTimer.isLock(ip,userName);
            if((boolean) lockMap.get("isLock")){
                map.put("msg", ResultState.LOGIN_LOCK);
                map.put("waitTime",lockMap.get("waitTime"));
                return map;
            }
            if ("1".equals(msg) && !imgCode.equalsIgnoreCase(verCode)) {
                map.put("msg", ResultState.CODE_ERROR);
                LoginRefreshTimer.maskRecord(ip,userName);
                return map;
            }
            User user = userService.checkLogin(userName);
            password = UserUtil.MD5(password);
            if (user == null) {
                map.put("msg",  ResultState.USER_NAME_ERROR);
                LoginRefreshTimer.maskRecord(ip,userName);
                return map;
            }
            if (!user.getPassword().equals(password)) {
                map.put("msg", ResultState.USER_PASSWORD_ERROR);
                LoginRefreshTimer.maskRecord(ip,userName);
                return map;
            }
            LoginRefreshTimer.removeMask(ip,userName);
            //判断是否超时
            int result = DateUtil.DateCompare(user.getPasswordUpdateTime(),appConfig.getPasswordInvalid(),appConfig.getPasswordRemind());
            if(result == 10){
                map.put("msg",  result);
                return map;
            }
            map.put("status", ResultState.SUCCESS);
            session.setAttribute("userName", userName);
            session.setAttribute("password", password);
            session.setAttribute("loginUserId", user.getId());
            session.setAttribute("authUserName", user.getCompelltion());
            session.setAttribute("passwordState",result);
            if(result == 11){
                session.setAttribute("days",DateUtil.getDays(user.getPasswordUpdateTime(),appConfig.getPasswordInvalid(),appConfig.getPasswordRemind()));
            }
            Organization org = organizationService.findByOrgId(user.getOrgid());
            session.setAttribute("loginUserDeptName", org.getDeptname());
            List<AuthRole> roleList = userService.findRoleByUserId(user.getId());
            /**
             * 如果t_auth_role表中对应权限为“超级管理员”，那么他可以维护所有用户和所有部门，权限对应0
             * 如果t_auth_role表中对应权限为"总调"，那么他可以维护所有用户和部门，权限对应1
             * 如果t_auth_role表中对应权限为"普通"，那么他可以维护所在飞行队的用户和部门，权限对应2
             * 如果t_auth_role表中没有对应记录，则他没有任何权限(权限为-1)
             */
            if (roleList.size() > 0) {
                for (AuthRole r : roleList) {
                    if ("总调".equals(r.getRoleName())) {
                        session.setAttribute("isShowAll", "1");
                    } else if ("普通".equals(r.getRoleName())) {
                        session.setAttribute("isShowAll", "2");
                    }
                    if ("超级管理员".equals(r.getRoleName())) {
                        session.setAttribute("isShowAll", "0");
                    }
                }
            } else {
                session.setAttribute("isShowAll", "-1");
            }
        } catch (Exception e) {
            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
            map.put("status", ResultState.ERROR);
        }
        return map;
    }

    /**
     * 读取JSON文件获取页面展示的图片、链接地址、子系统名
     * 并返回到页面。将session中的用户名跟密码使用JWT转换为token
     *
     * @param req
     * @author houxy
     */
    @RequestMapping("/desktop")
    public String toDesktop(HttpServletRequest req, HttpSession session, String message) throws Exception {
        try {
            //获取session中的账号密码
            String username = (String) session.getAttribute("userName");
            String password = (String) session.getAttribute("password");
            int passwordState = (int) session.getAttribute("passwordState");
            if (username == null || password == null) {
                return "redirect:/";
            }
            //根据账号密码转换成Token
            String token = TokenUtil.getJWTString(username, password);
            List<App> list = new ArrayList<App>();
            String path = req.getSession().getServletContext().getRealPath("resources/app.json");
            String sets = App.ReadFile(path);
            JSONArray jsonArr = JSONArray.fromObject(sets);
            String[] url = new String[jsonArr.size()];
            String[] name = new String[jsonArr.size()];
            String[] icon = new String[jsonArr.size()];
            for (int i = 0; i < jsonArr.size(); i++) {
                url[i] = jsonArr.getJSONObject(i).getString("url");
                name[i] = jsonArr.getJSONObject(i).getString("name");
                icon[i] = jsonArr.getJSONObject(i).getString("icon");
            }
            for (int i = 0; i < url.length; i++) {
                App a = new App();
                a.setUrl(url[i]);
                a.setName(name[i]);
                a.setIcon(icon[i]);
                list.add(a);
            }
            req.setAttribute("urlInfo", list);
            req.setAttribute("token", token);
            if ("error".equals(message)) {
                message = "您无此权限！";
            }
            req.setAttribute("errorMessage", message);
            req.setAttribute("passwordState",passwordState);
            if(passwordState == 11){
                req.setAttribute("days",(int) session.getAttribute("days"));
            }
            return "desktop";
        } catch (Exception e) {
            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
        }
        return "error";
    }

    /**
     * 退出登录
     *
     * @param session
     * @return
     */
    @RequestMapping("logout")
    public String logout(HttpSession session) {
        session.removeAttribute("userName");
        session.removeAttribute("password");
        session.removeAttribute("loginUserId");
        session.removeAttribute("isShowAll");
        session.removeAttribute("authUserName");
        session.removeAttribute("loginUserDeptName");
        return "log_in";
    }

    /**
     * 修改密码
     */
    @RequestMapping("/resetPassword")
    @ResponseBody
    public Map<String, Object> resetPassword(String userName,String oldPassword, String newPassword, String confPassword,String key, HttpSession session) {
        Map<String, Object> map = new HashMap();
        try {
            if(userName == null){
                userName = (String)session.getAttribute("userName");
            }else{
                userName = CryptoUtil.decryptString(userName,key);
            }
            User user = userService.findUserByUserName(userName);
            map.put("status", ResultState.ERROR);
            if (user == null) {
                map.put("msg", ResultState.USER_NOT_EXIST);
                return map;
            }
            oldPassword = CryptoUtil.decryptString(oldPassword,key);
            oldPassword = UserUtil.MD5(oldPassword);
            if (!user.getPassword().equals(oldPassword)) {
                map.put("msg", ResultState.OLD_PASSWORD_ERROR);
                return map;
            }
            newPassword = CryptoUtil.decryptString(newPassword,key);
            if (newPassword != null && !"".equals(newPassword)) {
                newPassword = UserUtil.MD5(newPassword);
            } else {
                map.put("msg", ResultState.NEW_PASSWORD_NULL);
                return map;
            }
            confPassword = CryptoUtil.decryptString(confPassword,key);
            if (confPassword != null && !"".equals(confPassword)) {
                confPassword = UserUtil.MD5(confPassword);
            } else {
                map.put("msg", ResultState.CONF_PASSWORD_NULL);
                return map;
            }
            if (!newPassword.equals(confPassword)) {
                map.put("msg", ResultState.PASSWORD_INCONSISTENT);
                return map;
            }
            user.setPassword(newPassword);
            user.setPasswordUpdateTime(new Date());
            userService.updateUser(user);
            map.put("status", ResultState.SUCCESS);
            return map;
        } catch (Exception e) {
            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
            map.clear();
            map.put("status",ResultState.ERROR);
        }
        return map;
    }

    /**
     * 获取密钥
     * @return
     */
    @RequestMapping(value="/genaessecret",method = RequestMethod.POST)
    @ResponseBody
    public  Map<String, Object> genAesSecret(){
        Map<String, Object> map = new HashMap();
        try{
            map.put("status",ResultState.SUCCESS);
            map.put("key",CryptoUtil.genAesSecret());
        }catch (Exception e){
            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
            map.clear();
            map.put("status",ResultState.ERROR);
        }
        return map;
    }

    /**
     * 去各个子系统验证是否可以登入，及跳转后的url
     * @return
     */
//    @RequestMapping("checkToken")
//    @ResponseBody
//    public String checkToken(String url,String token){
//        return postDcl(url,token);
//    }

    /**
     * 跨域获取数据
     * @param url
     * @return
     */
//    public synchronized static String postDcl(String url,String token) {
//        String result = null;
//        CloseableHttpResponse response = null;
//        CloseableHttpClient httpclient = HttpClients.createDefault();
//        RequestConfig requestConfig = RequestConfig.custom()
//                .setConnectTimeout(5000).setConnectionRequestTimeout(1000)
//                .setSocketTimeout(5000).build();
//        HttpPost httppost = new HttpPost(url);
//        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
//        try {
//        nvps.add(new BasicNameValuePair("isPass", "true"));
//        nvps.add(new BasicNameValuePair("token", token));
//        httppost.setEntity(new UrlEncodedFormEntity(nvps));
//        response = httpclient.execute(httppost);
//        HttpEntity entity =  response.getEntity();
//        result = EntityUtils.toString(entity);
//        } catch (ClientProtocolException e) {
//            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
//            return null;
//        } catch (IOException e) {
//            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
//            return null;
//        }catch (Exception e){
//            Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
//            return null;
//        }finally {
//            try {
//                if (response != null) {
//                    response.close();
//                }
//            } catch (IOException e) {
//                Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
//            }
//            try {
//                if (httpclient != null) {
//                    httpclient.close();
//                }
//            } catch (IOException e) {
//                Log.error(ExceptionUtils.getFullStackTrace(e), LoginController.class);
//            }
//        }
//        return result;
//    }

}
